#!/usr/bin/perl

######################################################################
#
# freqs2tbl.pl
#
# $Id: freqs2tbl.pl 188 2014-02-24 02:50:52Z drj826@gmail.com $
#
# Convert a frequency listing (CSV format) to a Semantic Markup
# Language (SML) table.
#
#---------------------------------------------------------------------
# USAGE (execution)
#
#   perl freqs2tbl.pl --skip 1 --order 10 -- 2m-freqs.csv
#
#     --skip    | -s => comma separated list of lines to skip
#     --shade        => shade odd rows with grey background
#     --number       => number rows
#
#---------------------------------------------------------------------
# Description
#
#   I use these CSV column names in my Google Apps spreadsheet of
#   frequencies and repeater channels.  Some of them correspond to
#   those used by the Chirp radio programming software
#   (http://chirp.danplanet.com/).  This makes it easy to program my
#   radios using channels and frequencies from the spreadsheet.
#
# VHF/UHF CSV Columns
# ---+----------------+-----------------------------------------
#  0 | Frequency      | in MHz
#  1 | Duplex         | +/-
#  2 | Offset         | in MHz
#  3 | Tone           | Tone, TSQL
#  4 | rToneFreq      | encode tone (Hz)
#  5 | cToneFreq      | decode tone (Hz)
#  6 | DtcsCode       | DCS code
#  7 | DtcsPolarity   |
#  8 | Mode           | FM/NFM
#  9 | Coverage       | wide area/local
# 10 | Area           | major area
# 11 | Location       | repeater location
# 12 | Sponsor        |
# 13 | SponsorAcronym |
# 14 | SponsorURL     |
# 15 | Callsign       |
# 16 | Label 6        | 6 character label
# 17 | Label 7        | 7 character label
# 18 | Label 8        | 8 character label
# 19 | Use            | ham, law, fire, ems, sar, mun, pub, wx
# 20 | Comment        |
# 21 | Skip           | 'S' if channel should be skipped during scanning
# 22 | Power          | Low
# 23 | Ch List A      | channel number in radios with 500+ memories
#
# Produced Table Columns
# ---+----------------+-----------------------------------------
#  0 | Frequency      | 146.970 FM
#  1 | Offset         | -0.6
#  2 | Enc/Dec        | 100.0
#  3 | Location       | Colorado Springs, Pikes Peak Summit (Wide Area Coverage)
#  4 | Owner          | KB0SRJ, Pikes Peak FM Association
#  5 | Notes          | Can be linked to 448.450
#
######################################################################

use strict;
use Text::CSV;
use Getopt::Long qw(:config no_ignore_case);

my @skip;                               # list of lines to skip
my $shade;                              # shade odd row backgrounds
my $number;                             # show row numbers

GetOptions
  (
   "skip|s=s"    => \@skip,
   "shade|g!"    => \$shade,
   "number|g!"   => \$number,
  );

@skip = split(',',join(',',@skip));

my %skip_line;                          # lines to skip
foreach my $line (@skip) {
  $skip_line{$line} = 1;
}

my $file = shift;                       # CSV file to parse
my $data = read_csv_file($file);
my $row  = 0;
my $ord  = 'odd';

foreach my $record ( @{ $data })
  {
    ++ $row;

    my $frequency = "!!$record->[0]!!";

    if ( $record->[8] )
      {
	$frequency .= " $record->[8]";
      }

    if ( $record->[17] )
      {
	$frequency .= " [linebreak] $record->[17]";
      }

    my $offset    = $record->[1] . $record->[2];
    my $encdec    = $record->[3];

    $encdec .= " $record->[4]" if $record->[4];
    $encdec .= "/$record->[5]" if $record->[5];

    my $location  = $record->[10];

    $location .= ", $record->[11]" if $record->[11];
    $location .= " ($record->[9] coverage)" if $record->[9];

    my $sponsor = q{};

    if ( $record->[12] and $record->[14] )
      {
	$sponsor = "[url:$record->[14]|$record->[12]]";
      }

    elsif ( $record->[12] )
      {
	$sponsor = "$record->[12]";
      }

    my $owner   = q{};

    if ( $record->[15] and $sponsor )
      {
	$owner = join(', ',$record->[15],$sponsor);
      }

    elsif ( $record->[15] )
      {
	$owner = "$record->[15]";
      }

    elsif ( $sponsor )
      {
	$owner = $sponsor;
      }

    if ( $record->[13] )
      {
	$owner .= " ($record->[13])";
      }

    my $notes = $record->[20];

    my $cell    = ': ';

    if ( $shade and $ord eq 'even' )
      {
	$cell = ': ';
	$ord  = 'odd';
      }

    elsif ( $shade and $ord eq 'odd' )
      {
	$cell = ':litegrey: ';
	$ord  = 'even';
      }

    if ( $number )
      {
	print <<"END_OF_TEXT";

$cell $row

END_OF_TEXT
      }

    print <<"END_OF_TEXT";

$cell $frequency

$cell $offset

$cell $encdec

$cell $location

$cell $owner

$cell $notes

---
END_OF_TEXT

  }

######################################################################

sub read_csv_file {

  my $file = shift;

  my $data = [];
  my $line = 0;

  open my $fh, "< :encoding(UTF-8)", $file or die "$file not readable";
  while (<$fh>) {
    ++ $line;
    next if $skip_line{$line};
    my $csv    = Text::CSV->new();
    my $status = $csv->parse($_);
    my $record = [ $csv->fields() ];
    push( @{$data}, $record );
  }
  close $fh;

  return $data;
}

######################################################################

1;
